﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using BattleCity.GameLogic;

namespace BattleCity.Rendering
{
    public class BulletsRenderer
    {
        VertexBuffer playerBulletVB;
        VertexBuffer enemyBulletVB;
        VertexBuffer renforcedBulletVB;

        GraphicsDevice graphicsDevice;

        Model bulletModel;
        BasicEffect bulletFx;

        Matrix translation;


        public Texture2D bulletsTexture;
        public BulletsRenderer(ContentManager content, GraphicsDevice graphicsDevice, ref BasicEffect effect)
        {
            bulletsTexture = content.Load<Texture2D>(@"other_textures/bullets_texture");

            bulletModel = content.Load<Model>(@"other_models/ammo");

            this.graphicsDevice = graphicsDevice;

            VertexPositionTexture[] vertexArray = new VertexPositionTexture[6];
            vertexArray[0] = new VertexPositionTexture(new Vector3(-0.65f, 1, 0.65f), new Vector2(0, 0.5f));
            vertexArray[1] = new VertexPositionTexture(new Vector3(-0.65f, 1, -0.65f), new Vector2(0, 0));
            vertexArray[2] = new VertexPositionTexture(new Vector3(0.65f, 1, -0.65f), new Vector2(0.5f, 0));
            vertexArray[3] = new VertexPositionTexture(new Vector3(0.65f, 1, -0.65f), new Vector2(0.5f, 0));
            vertexArray[4] = new VertexPositionTexture(new Vector3(0.65f, 1, 0.65f), new Vector2(0.5f, 0.5f));
            vertexArray[5] = new VertexPositionTexture(new Vector3(-0.65f, 1, 0.65f), new Vector2(0, 0.5f));

            enemyBulletVB = new VertexBuffer(graphicsDevice, VertexPositionTexture.VertexDeclaration, vertexArray.Length, BufferUsage.None);
            enemyBulletVB.SetData<VertexPositionTexture>(vertexArray);

            vertexArray[0] = new VertexPositionTexture(new Vector3(-0.65f, 1, 0.65f), new Vector2(0.5f, 0.5f));
            vertexArray[1] = new VertexPositionTexture(new Vector3(-0.65f, 1, -0.65f), new Vector2(0.5f, 0));
            vertexArray[2] = new VertexPositionTexture(new Vector3(0.65f, 1, -0.65f), new Vector2(1, 0));
            vertexArray[3] = new VertexPositionTexture(new Vector3(0.65f, 1, -0.65f), new Vector2(1, 0));
            vertexArray[4] = new VertexPositionTexture(new Vector3(0.65f, 1, 0.65f), new Vector2(1, 0.5f));
            vertexArray[5] = new VertexPositionTexture(new Vector3(-0.65f, 1, 0.65f), new Vector2(0.5f, 0.5f));

            playerBulletVB = new VertexBuffer(graphicsDevice, VertexPositionTexture.VertexDeclaration, vertexArray.Length, BufferUsage.None);
            playerBulletVB.SetData<VertexPositionTexture>(vertexArray);

            vertexArray[0] = new VertexPositionTexture(new Vector3(-0.8f, 1, 0.8f), new Vector2(0.5f, 1.0f));
            vertexArray[1] = new VertexPositionTexture(new Vector3(-0.8f, 1, -0.8f), new Vector2(0.5f, 0.5f));
            vertexArray[2] = new VertexPositionTexture(new Vector3(0.8f, 1, -0.8f), new Vector2(1.0f, 0.5f));
            vertexArray[3] = new VertexPositionTexture(new Vector3(0.8f, 1, -0.8f), new Vector2(1.0f, 0.5f));
            vertexArray[4] = new VertexPositionTexture(new Vector3(0.8f, 1, 0.8f), new Vector2(1.0f, 1.0f));
            vertexArray[5] = new VertexPositionTexture(new Vector3(-0.8f, 1, 0.8f), new Vector2(0.5f, 1.0f));

            renforcedBulletVB = new VertexBuffer(graphicsDevice, VertexPositionTexture.VertexDeclaration, vertexArray.Length, BufferUsage.None);
            renforcedBulletVB.SetData<VertexPositionTexture>(vertexArray);

           
            foreach (BasicEffect fx in bulletModel.Meshes[0].Effects)
            {
                fx.TextureEnabled = false;
                fx.Projection = effect.Projection;
                fx.LightingEnabled = true;
                fx.DiffuseColor = new Vector3(0.69f, 0.87f, 0.32f);
                fx.DiffuseColor = new Vector3(0.33f, 0.39f, 0.87f); 
            }

            bulletFx = new BasicEffect(graphicsDevice);
            bulletFx = (BasicEffect)bulletModel.Meshes[0].Effects[0];

            translation = Matrix.CreateTranslation(Vector3.Zero);
        }

        public void Draw(ref BasicEffect effect)
        {
            bulletFx.View = effect.View;

            graphicsDevice.SetVertexBuffer(enemyBulletVB);
            foreach (var bullet in GameState.gameState.EnemiesBulletList.Value)
            {
                translation.Translation = bullet.Item1.position.Value.xnaVector3YView;
                effect.World = translation;
                effect.CurrentTechnique.Passes[0].Apply();
               
                graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
            }

            graphicsDevice.SetVertexBuffer(playerBulletVB);
            foreach (var bullet in GameState.gameState.BulletList.Value)
            {
                if (bullet.power == 1)
                {
                    translation.Translation = bullet.position.Value.xnaVector3YView;
                    effect.World = translation;
                    effect.CurrentTechnique.Passes[0].Apply();

                    graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
                }
            }

            graphicsDevice.SetVertexBuffer(renforcedBulletVB);
            foreach (var bullet in GameState.gameState.BulletList.Value)
            {
                if (bullet.power == 2)
                {
                    translation.Translation = bullet.position.Value.xnaVector3YView;
                    effect.World = translation;
                    effect.CurrentTechnique.Passes[0].Apply();

                    graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
                }
            }

            if (Options.enhancedBullets)
            {
                graphicsDevice.Indices = bulletModel.Meshes[0].MeshParts[0].IndexBuffer;
                graphicsDevice.SetVertexBuffer(bulletModel.Meshes[0].MeshParts[0].VertexBuffer);

                bulletFx.DiffuseColor = new Vector3(0.69f, 0.87f, 0.32f);
                foreach (var bullet in GameState.gameState.BulletList.Value)
                {
                    if (bullet.power == 1)
                    {
                        translation.Translation = bullet.position.Value.xnaVector3YView + new Vector3(0, 0.8f, -0.05f);
                        bulletFx.World = translation;
                        bulletFx.CurrentTechnique.Passes[0].Apply();

                        graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, bulletModel.Meshes[0].MeshParts[0].NumVertices, 0, bulletModel.Meshes[0].MeshParts[0].PrimitiveCount);
                    }
                }

                bulletFx.DiffuseColor = new Vector3(0.33f, 0.39f, 0.87f);
                foreach (var bullet in GameState.gameState.BulletList.Value)
                {
                    if (bullet.power == 2)
                    {
                        translation.Translation = bullet.position.Value.xnaVector3YView + new Vector3(0, 0.8f, -0.05f);
                        bulletFx.World = translation;
                        bulletFx.CurrentTechnique.Passes[0].Apply();

                        graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, bulletModel.Meshes[0].MeshParts[0].NumVertices, 0, bulletModel.Meshes[0].MeshParts[0].PrimitiveCount);
                    }
                }

                bulletFx.DiffuseColor = new Vector3(1, 0.6f, 0.6f);
                foreach (var bullet in GameState.gameState.EnemiesBulletList.Value)
                {
                    translation.Translation = bullet.Item1.position.Value.xnaVector3YView + new Vector3(0, 0.8f, -0.05f);
                    bulletFx.World = translation;
                    bulletFx.CurrentTechnique.Passes[0].Apply();

                    graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, bulletModel.Meshes[0].MeshParts[0].NumVertices, 0, bulletModel.Meshes[0].MeshParts[0].PrimitiveCount);
                }
            }
        }
    }
}
